package core;

import java.util.*;
import core.ChemicalSystem;
import core.Component;
import core.Equilibrium;
import core.Specie;
import core.exceptions.*;

 /**
  * This is the Controller for the Model containing the ChemicalSystem and
  * related classes. It provides all of the functionality needed to build a
  * ChemicalSystem and perform operation on the ChemicalSystem.
  * @author Aaron A. Lovato
  */
public class SystemController extends Observable implements Observer
{
    //The system we are representing
    private ChemicalSystem system; 
    
    /**
     * Create the system being represented.
     * @param systemName The name of the system being represented.
     */
    public SystemController(String systemName)
    {
        system = new ChemicalSystem(systemName);
        system.setMaxIterations(40);
        system.setTolerance(10E-2);
        system.addObserver(this);
    }
    
    /**
     * Set the temperature in the system.
     * @param temperature The temperature in the system.
     */
    public void setTemperature(double temperature)
    {
        system.setTemp(temperature);
    }
    
    /**
     * Set the name of the system.
     * @param name The name of the system.
     */
    public void setName(String name)
    {
        system.setName(name);
    }
    
    /**
     * Set the ionic strength of the system.
     * @param ionicStrength The ionic strength of the system
     */
    public void setIonicStrength(double ionicStrength)
    {
        system.setIonicStrength(ionicStrength);
    }
    
    /**
     * Set the maximum iterations allowed when solving the system.
     * @param iterations The maximum iterations allowed when solving the system.
     */
    public void setMaxIterations(int iterations)
    {
        system.setMaxIterations(iterations);
    }
    
    /**
     * Set the tolerance required to determine when the system has
     * been solved.
     * @param tolerance The cutoff point for the error in the system
     * when it becomes "solved"
     */
    public void setTolerance(double tolerance)
    {
        system.setTolerance(tolerance);
    }
    
    /**
     * Add an equilibrium to the system.
     * @param equation The equilibrium equation.
     * @param k The equilibrium constant.
     */
    public void addEquilibrium(String equation, double k)
    {
        Equilibrium temp = new Equilibrium(system, equation, k);
        try
        {
            temp.parseEquation();
            system.addEquilibrium(temp);
        }
        catch (InvalidEquation e)
        {
            System.out.println("bad equation");
        }

        setChanged();
        notifyObservers();
    }
    
    /**
     * Clear the equilibria from the system.
     */
    public void clearEquilibria()
    {
       system.clearEquilibria(); 
    }
    /**
     * Clear the species from the system.
     */
    public void clearSpecies()
    {
       system.clearSpecies(); 
    }
    
    /**
     * Clear the components from the system.
     */
    public void clearComponents()
    {
       system.clearComponents(); 
    }
    
    /**
     * Add a specie to the system.
     * @param Equation The specie's formation equation
     * @param type The specie's type
     * @param logK The log of the specie's equilibrium constant
     * @param deltaH The specie's enthalpy of formation
     * @param deltaS The specie's entropy of formation
     */
    public void addSpecie(String equation, String type, double logK, double deltaH, double deltaS)
    {
        Specie temp = new Specie(equation);
        temp.setType(type);
        temp.setLogK(logK);
        temp.setDeltaH(deltaH);
        temp.setDeltaS(deltaS);
        system.addSpecie(temp);
    }
    
    /**
     * Add a component to the system.
     * @param name The name of the component.
     * @param type The component's type.
     * @param totalMolarity The component's total molarity
     * @param freeMolarity The component's free molarity/free molarity guess.
     */
    public void addComponent(String name, String type, double totalMolarity, double freeMolarity)
    {
        Component temp = new Component(name);
        temp.setType(type);
        temp.setTotalMolarity(totalMolarity);
        temp.setFreeMolarity(freeMolarity);
        system.addComponent(temp);
    }
    
    /**
     * Gets the list of valid component states.
     * @return States An array containing the valid states a component can have.
     */
    public Vector getComponentStates()
    {
        return Component.getTypes();
    }
    
    /**
     * Gets the list of valid specie states.
     * @return States An array containing the valid states a specie can have.
     */
    public Vector getSpecieStates()
    {
        return Specie.getTypes();
    }    
    
    /**
     * Gets the list of Species in the system.
     * @return specieList The species in the system
     */
    public Vector<Specie> getSpecies()
    {
        return system.getSpecies();
    }
    
    /**
     * Gets the list of Components in the system.
     * @return specieList The species in the system
     */
    public Vector<Component> getComponents()
    {
        return system.getComponents();
    }
    
    /**
     * Gets the list of Equilibria in the system.
     * @return equilibriaList The equilibria in the system
     */
    public Vector<Equilibrium> getEquilibria()
    {
        return system.getEquilibria();
    }
    
    /**
     * Handles updates to the ChemicalSystem
     * @param system The system being observed
     * @param arg The argument passed to the notifyObservers method
     */
    public void update(Observable system, Object arg)
    {
    }
}